package com.advaita.xml;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;

import nu.xom.Builder;
import nu.xom.Comment;
import nu.xom.Document;
import nu.xom.Element;
import nu.xom.Elements;
import nu.xom.ParsingException;
import nu.xom.Serializer;

import com.advaita.license.Customer;
import com.advaita.license.LicenseKey;

public final class CustomerListHandler {

	private static final String DEF_CUST_LIST_FILE = "CustomerList.xml";
	private static final String CUST_LIST_TAG = "CustomerList";
	private static final String CUST_ELEMENT_TAG = "Customer";
	private static final String CUST_NAME_TAG = "Name";
	private static final String CUST_KEY_TAG = "Key";
	private static final String CUST_EXPDATE_TAG = "ExpirationDate";

	private static final DateFormat dateFormatter = new SimpleDateFormat(
			"MM/dd/yy");

	// private constructor to avoid unnecessary instantiation of the class
	public CustomerListHandler() {
		// do not instantiate
	}

	public static ArrayList<Customer> readCustomerList() {
		return readCustomerList(DEF_CUST_LIST_FILE);
	}

	public static ArrayList<Customer> readCustomerList(String customerListFile) {

		ArrayList<Customer> custList = null;
		String expDateValue = null;

		try {
			custList = new ArrayList<Customer>();
			Builder builder = new Builder();
			File xmlFile = new File(customerListFile);
			Document xmlDoc = builder.build(xmlFile);
			Element root = xmlDoc.getRootElement();
			Elements customers = root.getChildElements();

			// Sanity check that we have "customer" elements here
			if (customers.size() > 0
					& !customers.get(0).getQualifiedName()
							.equals(CUST_ELEMENT_TAG)) {
				System.out.println("The Customer List file ["
						+ customerListFile
						+ "] file does not contain required element ["
						+ CUST_ELEMENT_TAG + "].");
				return null;
			}

			for (int i = 0; i < customers.size(); i++) {
				Element cust = customers.get(i);

				Element user = cust.getFirstChildElement(CUST_NAME_TAG);
				if (user == null) {
					System.out.println("The Customer List file ["
							+ customerListFile
							+ "] file does not contain required field ["
							+ CUST_NAME_TAG + "].");
					return null;
				}

				Element expDate = cust.getFirstChildElement(CUST_EXPDATE_TAG);
				if (expDate == null) {
					System.out.println("The Customer List file ["
							+ customerListFile
							+ "] file does not contain required field ["
							+ CUST_EXPDATE_TAG + "].");
					return null;
				}

				Element licKey = cust.getFirstChildElement(CUST_KEY_TAG);
				if (licKey == null) {
					System.out.println("The Customer List file ["
							+ customerListFile
							+ "] file does not contain required field ["
							+ CUST_KEY_TAG + "].");
					return null;
				}

				LicenseKey newLicKey = new LicenseKey();
				newLicKey.setKey(licKey.getChild(0).getValue());
				expDateValue = expDate.getChild(0).getValue();
				newLicKey.setExpDate(dateFormatter.parse(expDateValue));

				Customer newCust = new Customer();
				newCust.setUser(user.getChild(0).getValue());
				newCust.setLicenseInfo(newLicKey);
				custList.add(newCust);
			}

		} catch (ParsingException e) {
			System.out.println("The Customer List file [" + customerListFile
					+ "] file does not contain valid XML: " + e);
			return null;
		} catch (FileNotFoundException e) {
			System.out.println("The Customer List file [" + customerListFile
					+ "] does not exist.");
		} catch (IOException e) {
			System.out.println("The Customer List file [" + customerListFile
					+ "] does not contain valid XML: " + e);
			return null;
		} catch (ParseException e) {
			System.out.println("The Customer List file [" + customerListFile
					+ "] contains an invalid date: " + expDateValue);
			return null;
		} catch (Exception e) {
			System.out
					.println("Unexpected exception processing Customer List file ["
							+ customerListFile + "] :" + e);
			return new ArrayList<Customer>();
		}
		return (custList);
	}

	public static void writeCustomerList(ArrayList<Customer> customerList) {
		writeCustomerList(customerList, DEF_CUST_LIST_FILE);
	}

	public static void writeCustomerList(ArrayList<Customer> customerList,
			String customerListFile) {

		// Build XML document from customerList
		Element custList = new Element(CUST_LIST_TAG);

		for (Customer cust : customerList) {

			Element nameElement = new Element(CUST_NAME_TAG);
			nameElement.appendChild(cust.getUser());

			Element licKeyElement = new Element(CUST_KEY_TAG);
			licKeyElement.appendChild(cust.getLicenseInfo().getKey());

			Element expDateElement = new Element(CUST_EXPDATE_TAG);
			expDateElement.appendChild(dateFormatter.format(cust
					.getLicenseInfo().getExpDate()));

			Element custElement = new Element(CUST_ELEMENT_TAG);
			custElement.appendChild(nameElement);
			custElement.appendChild(licKeyElement);
			custElement.appendChild(expDateElement);
			custList.appendChild(custElement);
		}
		Document xmlDoc = new Document(custList);

		// Save the XML document
		try {
			// Add a time stamp comment
			Comment timestamp = new Comment("File Created "
					+ new java.util.Date());
			xmlDoc.insertChild(timestamp, 0);

			// Write the file with indentation via a serializer
			FileOutputStream xmlFile = new FileOutputStream(customerListFile);
			Serializer serializer = new Serializer(xmlFile, "UTF-8");
			serializer.setIndent(2);
			serializer.write(xmlDoc);
			xmlFile.close();
		} catch (IOException ioe) {
			System.out.println(ioe.getMessage());
		}
		return;
	}
}
